package org.dfl.core.data;

import java.util.Collection;

/**
 * Token's history. History keeps information about last unnest operation + previous history.
 * @author Piotr Wlodarczyk
 *
 */
public class History extends PureHistory {
	/** object corresponding to the last unnested collection or that collection **/
	private Object colElem;
	
	/**
	 * create an empty history
	 */
	public History() {
		super();
	}
	
	/**
	 * create a history for unnested empty collection
	 * @param history - previous history
	 */
	@SuppressWarnings("unchecked")
	public History(History history) {
		super(history);
		setColElem(getCol());
	}
	
	/**
	 * create a history with given parameters
	 * @param colElem - object corresponding to the last unnested collection or that collection
	 * @param col - last unnested collection
	 * @param history - previous history
	 */
	@SuppressWarnings("unchecked")
	public History(Object colElem, Collection col, History history) {
		super(col,history);
		setColElem(colElem);
	}

	public void setColElem(Object colElem) {
		if(colElem == colOrig){
			this.colElem = getCol();
		}else{
			this.colElem = colElem;
		}
	}
	
	public Object getColElem() {
		return colElem;
	}
	
	/**
	 * chcek if this history is a special history where collection == corresponding object
	 * @return
	 */
	public boolean isSpecial() {
		// should always be the same element (because if col is changed colElem should be changed as well)
		return getColElem() == getCol();
	}

	@Override
	public String toString(){
		return "<HIST>"+getColElem()+" of "+getCol()+"</HIST>";
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((colElem == null) ? 0 : colElem.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final History other = (History) obj;
		if (colElem == null) {
			if (other.colElem != null)
				return false;
		} else if (!colElem.equals(other.colElem))
			return false;
		return true;
	}
	
	public History getCopy(){
		History h = new History();
		h.setCol(getCol());
		if(colElem == getCol()){
			h.colElem = h.getCol();
		}else{
			h.colElem = getColElem();
		}
		if(getHistory()!=null){
			h.setHistory(getHistory().getCopy());
		}
		return h;
	}
}
